#include "View.h"

namespace Pulse
{
	AppView::AppView( void )
	{
		//AddScreen( new SampleScreen );

		// TODO: Create a manager or something to manage creation and deletion of actors
		m_pActorModel1 = this->GetLogic()->NewActor();
		m_pActorModel2 = this->GetLogic()->NewActor();
		m_pActorModel3 = this->GetLogic()->NewActor();
		m_pActorCamera = this->GetLogic()->NewActor();
		m_pActorLight = this->GetLogic()->NewActor();

		ComponentModelRenderer *pModel1 = (ComponentModelRenderer*)m_pActorModel1->AddComponent( EComponent::RENDERER );
		ComponentModelRenderer *pModel2 = (ComponentModelRenderer*)m_pActorModel2->AddComponent( EComponent::RENDERER );
		ComponentModelRenderer *pModel3 = (ComponentModelRenderer*)m_pActorModel3->AddComponent( EComponent::RENDERER );
		ComponentCamera *pCamera = (ComponentCamera*)m_pActorCamera->AddComponent( EComponent::CAMERA );
		ComponentLight *pLight = (ComponentLight*)m_pActorLight->AddComponent( EComponent::LIGHT );
		
		// Set camera settings
		const DisplayMode *pDP = &Engine::GetInstance()->GetEngineSettings()->displaySettings;
		FLOAT aspect = (FLOAT)pDP->width / (FLOAT)pDP->height;		
		pCamera->SetProjectionPerspective( 0.01f, 1000.0f, aspect, PSX_PI * 0.25f );
	
		// Set model
		EErrorCode::Type retCode = pModel1->LoadModel( PSX_String("SampleModel.mdl") );
		retCode = pModel2->LoadModel( PSX_String("humanoid.mdl") );
		retCode = pModel3->LoadModel( PSX_String("SadFace.mdl") );
	
		if ( retCode != EErrorCode::OKAY )
		{
			PSX_PushError( "Failed to load model!" );
		}

		// Set light
		m_pActorLight->SetPosition( 0.0f, 10.0f, -5.0f );
		pLight->SetColor( &Vector3( 1.0f, 1.0f, 1.0f ) );
		pLight->SetRange( 30.0f );

		m_scene.InsertActor( m_pActorModel1 );
		m_scene.InsertActor( m_pActorModel2 );
		m_scene.InsertActor( m_pActorModel3 );
		m_scene.InsertActor( m_pActorCamera );
		m_scene.InsertActor( m_pActorLight );

		m_scene.SetCamera( m_pActorCamera );

		m_pActorModel1->SetPosition( -20.0f, 5.0f, 0.0f );
		m_pActorModel2->SetPosition( 0.0f, 0.0f, 0.0f );
		m_pActorModel3->SetPosition( 20.0f, 5.0f, 0.0f );
	
		m_pActorModel2->SetScale( 0.15f );
		m_pActorModel3->SetScale( 0.15f );

		m_pActorCamera->SetPosition( 0.0f, 10.0f, -50.0f );
	}

	AppView::~AppView( void )
	{

	}

	void AppView::OnUpdate( DOUBLE time, FLOAT deltaTime )
	{
		static const float rotation = 0.05f;
		static const float position = 5.0f;

		m_pActorModel1->SetRotation( time * 2.0f, 0.0f, 0.0f );
		m_pActorModel2->SetRotation( 0.0f, time * 0.50f, 0.0f );
		m_pActorModel3->SetRotation( Math::Sinf( time ) * 0.50f, 180.0f, 0.0f );

		m_pActorLight->SetPosition( 0.0f, 20.0f, -5.0f - Math::Clamp( Math::Cosf( time * 1.75f ) * 10.0f, -100.0f, 100.0f ) );
		//ComponentLight *pLight = (ComponentLight*)m_pActorLight->AddComponent( EComponent::LIGHT );
		//pLight->SetRange( 10.0f + Math::Clamp( Math::Sinf( time ) * 40.0f, 0.0f, 50.0f ) );
		
		//m_pActorCamera->SetRotation( Math::Cosf( time ) * rotation, -Math::Sinf( time ) * rotation, Math::Sinf( time ) * rotation );
		//m_pActorCamera->SetPosition( Math::Cosf( time ) * position, Math::Sinf( time ) * position, -50.0f );

		m_scene.Update( deltaTime );
	}

	EErrorCode::Type AppView::OnRender( DOUBLE time, FLOAT deltaTime )
	{
		m_scene.Render();

		return EErrorCode::NONE;
	}
}